import { Icon } from '@/components/Icon';
import NavBar from '@/components/NavBar';
import { useAppSelector } from '@/store';
import {
  clearkeywordAction,
  clearSugestionAction,
  getSugestionAction,
  savekeywordAction,
} from '@/store/action/search';
import { useEffect, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import styles from './index.module.scss';
// DOMPurify防止xss攻击
import DOMPurify from 'dompurify';
import { setLocalHistories } from '@/utils/storage';
import { useHistory } from 'react-router-dom';
import { Toast } from 'antd-mobile';

export default function Search() {
  const history = useHistory();
  const [keyword, setKeyword] = useState('');
  const timeRef = useRef(0);
  const dispatch = useDispatch();
  const { suggestion, historuKeyword } = useAppSelector((state) => state.search);
  // 搜索处理函数
  const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = e.target.value.trim();
    setKeyword(val);
    // 防抖 作用：解决每输入一次都发起请求，减少处理次数优化性能
    // 1 每次点击都清除上次的定时器
    clearTimeout(timeRef.current);
    // 输入空 不执行下面
    if (!val) {
      // 留空时也要清除搜索建议
      return;
    }
    timeRef.current = window.setTimeout(() => {
      // 2 500毫秒之后发起请求 即最后一次在发请求
      dispatch(getSugestionAction(val));
    }, 500);
  };

  // 关键字高亮
  const highlight = (str: string, keyword: string) => {
    const reg = new RegExp(`(${keyword})`, 'gi');
    // 一个()对应的$1
    return str.replace(reg, '<span>$1</span>');
  };

  // 组件卸载清除搜索建议
  useEffect(() => {
    return () => {
      dispatch(clearSugestionAction());
    };
  }, [dispatch]);
  // 监听keyword的变化 清除搜索建议
  useEffect(() => {
    dispatch(clearSugestionAction());
  }, [keyword, dispatch]);
  // 监听historuKeyword更新时存储到本地
  useEffect(() => {
    setLocalHistories(historuKeyword);
  }, [historuKeyword]);

  // 保存搜索记录
  const handleSaveKeyword = () => {
    if (!keyword) return Toast.show({ content: '内容不能为空', duration: 1000 });
    dispatch(savekeywordAction(keyword));
    history.push({
      pathname: '/search/result',
      search: `q=${keyword}`,
    });
  };

  // 监听输入框的回车事件
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      handleSaveKeyword();
    }
  };
  return (
    <div className={styles.root}>
      {/* 顶部导航栏 */}
      <NavBar
        right={
          <span className="search-text" onClick={() => handleSaveKeyword()}>
            搜索
          </span>
        }
      >
        <div className="navbar-search">
          <Icon type="iconbtn_search" className="icon-search" />

          <div className="input-wrapper">
            {/* 输入框 */}
            <input
              type="text"
              placeholder="请输入关键字搜索"
              onChange={handleSearch}
              value={keyword}
              onKeyDown={handleKeyDown}
            />

            {/* 清空输入框按钮 */}
            <Icon type="iconbtn_tag_close" className="icon-close" onClick={() => setKeyword('')} />
          </div>
        </div>
      </NavBar>

      {/* 搜索历史和结果的二选一 */}
      {!keyword ? (
        // {/* 搜索历史 */}
        <div className="history" style={{ display: 'block' }}>
          {!!historuKeyword.length && (
            <div className="history-header">
              <span>搜索历史</span>
              <span
                onClick={() => {
                  dispatch(clearkeywordAction());
                }}
              >
                <Icon type="iconbtn_del" />
              </span>
            </div>
          )}

          <div className="history-list">
            {historuKeyword.map((item, index) => {
              return (
                <span key={index} className="history-item">
                  {item}
                  <span className="divider"></span>
                </span>
              );
            })}
          </div>
        </div>
      ) : (
        // {/* 搜素建议结果列表 */}
        <div className="search-result">
          {suggestion.map((item) => {
            return (
              <div className="result-item" key={item}>
                <Icon className="icon-search" type="iconbtn_search" />
                <div
                  className="result-value"
                  // 类似vue中v-html
                  // React中不能同时使用dangerouslySetInnerHTML和插槽 不然会报错 __html固定语法
                  // DOMPurify 可以过滤那些恶意添加的事件等
                  dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(highlight(item, keyword)) }}
                >
                  {/* {item} */}
                  {/* <span>{'高亮'}</span> {`其余`} */}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
